package com.ahnu.tongue.service.impl;

import com.ahnu.tongue.common.BusinessException;
import com.ahnu.tongue.config.DeepSeekConfig;
import com.ahnu.tongue.service.AIService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@RequiredArgsConstructor
public class AIServiceImpl implements AIService {

    private final RestTemplate restTemplate;
    private final DeepSeekConfig deepSeekConfig;

    @Value("${python.model.path}")
    private String pythonModelPath;

    @Value("${python.interpreter}")
    private String pythonInterpreter;

    @Value("${python.timeout:30}")
    private int pythonTimeout;

    @Override
    public Map<String, String> analyzeTongueImage(File imageFile) {
        if (imageFile == null || !imageFile.exists()) {
            throw new IllegalArgumentException("图片文件不存在");
        }

        try {
            // 验证Python模型文件
            File modelFile = new File(pythonModelPath);
            if (!modelFile.exists()) {
                throw new BusinessException("AI模型文件不存在");
            }

            // 构建Python命令
            ProcessBuilder processBuilder = new ProcessBuilder(
                pythonInterpreter,
                pythonModelPath,
                imageFile.getAbsolutePath()
            );
            
            // 设置工作目录
            processBuilder.directory(modelFile.getParentFile());
            
            // 合并错误流到标准输出流
            processBuilder.redirectErrorStream(true);
            
            log.info("开始调用Python模型分析图片: {}", imageFile.getName());
            
            // 启动进程
            Process process = processBuilder.start();
            
            // 读取输出
            StringBuilder output = new StringBuilder();
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    output.append(line).append("\n");
                }
            }
            
            // 等待进程完成，设置超时时间
            if (!process.waitFor(pythonTimeout, TimeUnit.SECONDS)) {
                process.destroy();
                throw new BusinessException("模型分析超时，请稍后重试");
            }
            
            // 检查返回值
            int exitCode = process.exitValue();
            if (exitCode != 0) {
                log.error("Python模型执行失败，退出码: {}, 输出: {}", exitCode, output);
                throw new BusinessException("模型分析失败，请稍后重试");
            }
            
            // 解析JSON输出
            String outputStr = output.toString().trim();
            if (!StringUtils.hasText(outputStr)) {
                throw new BusinessException("模型未返回分析结果");
            }

            try {
                Map<String, String> result = JSON.parseObject(outputStr, Map.class);
                validateAnalysisResult(result);
                return result;
            } catch (Exception e) {
                log.error("解析模型输出失败: {}", outputStr, e);
                throw new BusinessException("解析分析结果失败");
            }
            
        } catch (IOException e) {
            log.error("调用Python模型失败", e);
            throw new BusinessException("图片分析失败，请稍后重试");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new BusinessException("图片分析被中断");
        }
    }

    private void validateAnalysisResult(Map<String, String> result) {
        if (result == null || result.isEmpty()) {
            throw new BusinessException("模型返回结果为空");
        }
        
        String[] requiredFields = {"color", "coating", "shape", "moisture"};
        for (String field : requiredFields) {
            if (!result.containsKey(field) || !StringUtils.hasText(result.get(field))) {
                throw new BusinessException("模型返回结果不完整: 缺少" + field);
            }
        }
    }

    @Override
    public String generateHealthSuggestion(String diagnosis) {
        if (!StringUtils.hasText(diagnosis)) {
            throw new IllegalArgumentException("诊断结果不能为空");
        }

        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + deepSeekConfig.getApiKey());

            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("model", "deepseek-chat");

            List<Map<String, String>> messages = new ArrayList<>();
            
            // 系统提示词
            Map<String, String> systemMessage = new HashMap<>();
            systemMessage.put("role", "system");
            systemMessage.put("content", 
                "你是一个专业的中医专家，请根据舌象诊断结果给出详细的健康建议。建议必须包含以下四个方面：\n" +
                "1. 身体状况分析：根据舌象特征分析当前的身体状况\n" +
                "2. 饮食建议：根据舌象特点给出具体的饮食调理方案\n" +
                "3. 生活作息建议：建议合适的作息时间和生活方式\n" +
                "4. 需要注意的事项：列出需要特别注意的健康事项\n" +
                "请确保建议具体实用，易于理解和执行。"
            );
            messages.add(systemMessage);

            // 用户输入
            Map<String, String> userMessage = new HashMap<>();
            userMessage.put("role", "user");
            userMessage.put("content", "请根据以下舌象诊断结果给出健康建议：\n" + diagnosis);
            messages.add(userMessage);

            requestBody.put("messages", messages);
            requestBody.put("temperature", 0.7);
            requestBody.put("max_tokens", 1000);
            requestBody.put("stream", false);

            HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);

            log.info("开始调用DeepSeek API生成健康建议");
            
            ResponseEntity<String> response = restTemplate.postForEntity(
                deepSeekConfig.getApiUrl() + "/chat/completions",
                request,
                String.class
            );

            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                JSONObject jsonResponse = JSON.parseObject(response.getBody());
                String suggestion = jsonResponse.getJSONArray("choices")
                    .getJSONObject(0)
                    .getJSONObject("message")
                    .getString("content");
                
                if (!StringUtils.hasText(suggestion)) {
                    throw new BusinessException("AI生成的建议内容为空");
                }
                
                return suggestion;
            }

            throw new BusinessException("生成健康建议失败，请稍后重试");
            
        } catch (HttpClientErrorException e) {
            log.error("调用DeepSeek API失败: {} - {}", e.getStatusCode(), e.getResponseBodyAsString(), e);
            if (e.getStatusCode() == HttpStatus.UNAUTHORIZED) {
                throw new BusinessException("AI服务认证失败，请检查API密钥");
            }
            throw new BusinessException("生成健康建议失败: " + e.getMessage());
        } catch (Exception e) {
            log.error("调用DeepSeek API失败", e);
            throw new BusinessException("生成健康建议失败，请稍后重试");
        }
    }
} 